'''
在TFT显示菜单并用编码器控制菜单需要以下步骤：

定义菜单结构：
创建一个菜单结构体，包含菜单项的名称、值和回调函数等信息。
定义菜单项的数量和菜单的层级结构。
初始化TFT显示屏：
初始化TFT显示屏的库和设置。
设置显示屏的方向、颜色和字体等。
显示菜单：
创建一个函数来显示菜单，包括菜单标题、菜单项和当前选中项等。
使用TFT显示屏的库来绘制菜单。
编码器控制菜单：
连接编码器到ESP32开发板的引脚。
使用编码器库来读取编码器的值。
根据编码器的值来更新菜单的当前选中项。
处理菜单项的回调函数：
创建一个函数来处理菜单项的回调函数。
根据菜单项的值来执行相应的操作。
'''
#include <TFT_eSPI.h>
#include <Encoder.h>

// 定义菜单结构体
struct MenuItem {
  String name;
  int value;
  void (*callback)();
};

// 定义菜单项
MenuItem menuItems[] = {
  {"Item 1", 1, item1Callback},
  {"Item 2", 2, item2Callback},
  {"Item 3", 3, item3Callback}
};

// 定义菜单的层级结构
int menuLevel = 0;
int menuItemCount = sizeof(menuItems) / sizeof(MenuItem);

// 初始化TFT显示屏
TFT_eSPI tft = TFT_eSPI();

// 初始化编码器
Encoder encoder(32, 33);

void setup() {
  Serial.begin(115200);
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  displayMenu();
}

void loop() {
  int encoderValue = encoder.read();
  if (encoderValue != 0) {
    updateMenu(encoderValue);
  }
  delay(50);
}

void displayMenu() {
  tft.fillScreen(TFT_BLACK);
  tft.drawString("Menu", 10, 10);
  for (int i = 0; i < menuItemCount; i++) {
    tft.drawString(menuItems[i].name, 10, 30 + i * 20);
  }
  tft.drawString(">", 10, 30 + menuLevel * 20);
}

void updateMenu(int encoderValue) {
  menuLevel += encoderValue;
  if (menuLevel < 0) {
    menuLevel = 0;
  } else if (menuLevel >= menuItemCount) {
    menuLevel = menuItemCount - 1;
  }
  displayMenu();
}

void item1Callback() {
  Serial.println("Item 1 selected");
}

void item2Callback() {
  Serial.println("Item 2 selected");
}

void item3Callback() {
  Serial.println("Item 3 selected");
}
